<?php
/**
 * Created by PhpStorm.
 * User: JHR
 * Date: 2018/9/27
 * Time: 11:24
 */
namespace app\manage\controller;
use my\MyRedis;
use think\Db;
use think\exception\HttpResponseException;
use think\facade\Cache;

class Login extends Base {

    public function login() {
        $post['username'] = input('post.username');
        $post['password'] = input('post.password');
        $electron = input('post.electron','');
        $recaptcha3  = config('recaptcha3');
        if($electron && $electron === 'electron') {
            $recaptcha3 = false;
        }
        if($recaptcha3 === true) {
            $post['token'] = input('post.token');
            checkPost($post);
            $data = [
                'secret' => '6LctqV4eAAAAANzuGpMbOswLWX9xTQ4HTrO0wilo',
                'response' => $post['token'],
            ];
            $url = 'https://www.recaptcha.net/recaptcha/api/siteverify';
            $result = curl_post_data($url,$data);
            $res_arr = json_decode($result,true);
            if($res_arr['success'] !== true) {
                return ajax($res_arr,57);
            }else {
                mylog('login',var_export($res_arr,true),'login.log');
                if($res_arr['score'] < 0.7) {
                    return ajax('',58);
                }
            }
        }else {
            checkPost($post);
        }
        $where = [
            ['username','=',$post['username']],
            ['password','=',md5($post['password'] . config('login_key'))]
        ];
        try {
            $result = Db::table('mp_admin')->where($where)->field('id AS admin_id,realname,username,avatar,email,status,role,last_login_province')->find();
            if(!$result) {
                return ajax('用户名密码不匹配',51);
            }else {
                if($result['status'] === 2 && $result['admin_id'] !== 1) {
                    return ajax('账号已冻结',55);
                }
                $location = $this->getLocation();
                if($result['last_login_province'] && $location['province'] !== $result['last_login_province']) {
                    //todo 警告! 正在跨省登录
                    $sendData = [
                        'plat' => $_SERVER['HTTP_HOST'],
                        'username' => $result['username'],
                        'province' => $location['province'],
                        'email' => $result['email'],
                    ];
                    $this->asyn_email_send($sendData);
                }
                $noncestr = randomkeys(6);
                $time = time();
                $token = md5($result['admin_id'] . $noncestr . $time);
                $insert_data = [
                    'admin_id' => $result['admin_id'],
                    'role' => $result['role'],
                    'token' => $token,
                    'create_time' => $time,
                    'login_type' => 5,
                    'ip' => $location['ip'],
                    'province' => $location['province']
                ];
                Db::table('mp_admin_token')->insert($insert_data);
                Db::table('mp_admin')->where($where)->update(['last_login_province'=>$location['province']]);
                $log_data = [
                    'type' => 0,
                    'admin_id' => $result['admin_id'],
                    'create_time' => $time,
                    'ip' => $location['ip'],
                    'region' => $location['province'],
                    'login_type' => 5,
                ];
                Db::table('mp_syslog')->insert($log_data);
            }
        }catch (\Exception $e) {
            return ajax($e->getMessage(),-1);
        }
        $redis = MyRedis::getInstance();
        $result['token'] = $token;
        $result['menuLit'] = $redis::get('route'.$result['role']);
        $result['menuLit'] = json_decode($result['menuLit'], true);
        return ajax($result);
    }

    public function checkToken() {
        $token = input('post.token');
        try {
            if(!$token) {
                return ajax('请传入token',-3);
            }else {
                $whereToken = [
                    ['token','=',$token]
                ];
                $token_exist = Db::table('mp_admin_token')->where($whereToken)->find();
                if(!$token_exist) {
                    return ajax('token无效',-3);
                }else {
                    if((time() - $token_exist['create_time']) > config('token_expires_time')) {
                        return ajax('token已过期',-3);
                    }
                }
            }
        } catch (\Exception $e) {
            return ajax($e->getMessage(),-1);
        }
        return ajax();
    }

    public function getQrcode() {
        $key = randomkeys(8);
        $value = randomkeys(4);
        $cache = [
            'value' => $value,
            'login' => 0,
            'token' => ''
        ];
        $redis = MyRedis::getInstance();
        $redis::set($key, json_encode($cache),120);
//        Cache::set($key,$cache,120);
        $data = [
            'key' => $key,
            'value' => $value
        ];
        $url = "http://wx.psn.asia/wechat/auth_user_admin?".http_build_query($data);
        $data['url'] = $url;
        return ajax($data);
    }

    public function checkQrcodeState() {
        $key = input('post.key');
        $value = input('post.value');
        if($key) {
            $redis = MyRedis::getInstance();
            $cache = $redis::get($key);
            if (!$cache) {
                return ajax('二维码已过期',52);
            }
            $cache = json_decode($cache,true);
            if(!$cache) {
                return ajax('json_decode失败',52);
            }
            if ($cache["value"] !== $value) {
                return ajax('二维码验证失败',62);
            }
//            $cache = Cache::get($key);
//            if(!$cache) {
//                return ajax('二维码已过期',52);
//            }
//            if($cache['value'] !== $value) {
//                return ajax('缓存异常',62);
//            }
//            if($cache['login'] === 1) {
//                Cache::rm($key);
//            }
            return ajax($cache);
        }else {
            return ajax('',-1);
        }
    }


    public function auth_user(){
        if (!isset($_GET['code'])){ //没有code，去微信接口获取code码
            $callback = $_SERVER['REQUEST_SCHEME'] . '://'.$_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
            $this->get_code($callback);
        } else {    //获取code后跳转回来到这里了
            $code = $_GET['code'];
            $data = $this->get_access_token($code);//获取网页授权access_token和用户openid
            $data_all = $this->get_user_info($data['access_token'],$data['openid']);//获取微信用户信息
            $whereAdmin = [
                ['wx_openid','=',$data_all['openid']]
            ];
            $user_exist = Db::table('mp_admin')->where($whereAdmin)->find();
            $time = time();
            if($user_exist) {
                if($user_exist['status'] === 2 && $user_exist['id'] !== 1) {
                    die('<h1>账号已冻结</h1>');
                }
                $admin_id = $user_exist['id'];
                $role = $user_exist['role'];
                $realname = $user_exist['realname'] ? $user_exist['realname'] : $data_all['nickname'];
//                $realname =  $data_all['nickname'];
                $avatar = $user_exist['avatar'] ? $user_exist['avatar'] : $data_all['headimgurl'];
                $update_data = [
                    'realname' => $realname,
                    'avatar' => $avatar
                ];
                Db::table('mp_admin')->where($whereAdmin)->update($update_data);
            }else {
                $insert_data = [
                    'role' => 2,
                    'wx_openid' => $data_all['openid'],
                    'realname' => $data_all['nickname'],
                    'avatar' => $data_all['headimgurl'],
                    'create_time' => $time
                ];
                $admin_id = Db::table('mp_admin')->insertGetId($insert_data);
                $role = 2;
            }
            $token = md5($time . $admin_id);
            $insert_data = [
                'admin_id' => $admin_id,
                'role' => $role,
                'token' => $token,
                'create_time' => $time,
                'login_type' => 2
            ];
            Db::table('mp_admin_token')->insert($insert_data);
            $key = $_GET['key'];
            $value = $_GET['value'];
            if($key) {
                $cache = Cache::get($key);
                if(!$cache) {
                    die('二维码已过期');
                }
                if($cache['value'] !== $value) {
                    die('缓存异常');
                }
                $cache['token'] = $token;
                $cache['login'] = 1;
                Cache::set($key,$cache,6);
                $backurl = $_SERVER['REQUEST_SCHEME'] . '://'.$_SERVER['HTTP_HOST'] . '/static/loginsuccess.html?avatar=' . urlencode($data_all['headimgurl']);
                header('Location:'. $backurl);exit();
            }
            exit('login success');
        }

    }
    /**
     * 2、用户授权并获取code
     * @param string $callback 微信服务器回调链接url
     */
    private function get_code($callback,$scope = 'snsapi_userinfo'){
        $appid = config('appid');
        $state = md5(uniqid(rand(), true));//唯一ID标识符绝对不会重复
        $url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' . $appid . '&redirect_uri=' . urlencode($callback) .  '&response_type=code&scope=' . $scope . '&state=' . $state . '#wechat_redirect';
        header("Location:".$url);exit;
    }
    /**
     * 3、使用code换取access_token
     * @param string 用于换取access_token的code，微信提供
     * @return array access_token和用户openid数组
     */
    private function get_access_token($code){
        $appid = config('appid');
        $appsecret = config('app_secret');
        $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $appid . '&secret=' . $appsecret . '&code=' . $code . '&grant_type=authorization_code';
        $user = json_decode(file_get_contents($url));
        if (isset($user->errcode)) {
            if($user->errcode == '40163') {
//                    echo 'Code been used!';exit;
                throw new HttpResponseException(ajax('Code been used!',-1));
            }else {
//                    echo 'error:' . $user->errcode.'<hr>msg :' . $user->errmsg;exit;
                throw new HttpResponseException(ajax($user->errmsg,-1));
            }
        }
        $data = json_decode(json_encode($user),true);//返回的json数组转换成array数组
        return $data;
    }
    /**
     * 4、使用access_token获取用户信息
     * @param string access_token
     * @param string 用户的openid
     * @return array 用户信息数组
     */
    private function get_user_info($access_token,$openid){
        $url = 'https://api.weixin.qq.com/sns/userinfo?access_token=' . $access_token . '&openid=' . $openid . '&lang=zh_CN';
        $user = json_decode(file_get_contents($url));
        if (isset($user->errcode)) {
//            echo 'error:' . $user->errcode.'<hr>msg  :' . $user->errmsg;exit;
            throw new HttpResponseException(ajax($user->errmsg,49));
        }
        $data = json_decode(json_encode($user),true);//返回的json数组转换成array数组
        return $data;
    }

    public function getCode() {
        if(!isset($_GET['code'])) {
            $callback = $_SERVER['REQUEST_SCHEME'] . '://'.$_SERVER['HTTP_HOST'] . '/api/login/getCode';  //微信服务器回调url，这里是本页url
            $this->get_code($callback);
        }else {
            echo($_GET['code']);
        }
    }

    //高德地图获取地理位置
    private function getLocation() {
        $ip = $this->getip();
        $parameters = [
            'key' => '3a69bef99855dc5d7e80809e59111a4b',
            'ip' => $ip,
        ];
        $url = 'https://restapi.amap.com/v3/ip?'.http_build_query($parameters);
        $res = curl_get_data($url);
        $res = json_decode($res,true);
        $res['ip'] = $ip;
        return $res;
    }

    protected function getip() {
        $unknown = 'unknown';
        if ( isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] && strcasecmp($_SERVER['HTTP_X_FORWARDED_FOR'], $unknown) ) {
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } elseif ( isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], $unknown) ) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        /*
        处理多层代理的情况
        或者使用正则方式：$ip = preg_match("/[\d\.]{7,15}/", $ip, $matches) ? $matches[0] : $unknown;
        */
        if (false !== strpos($ip, ',')) {
            $ip_arr = explode(',', $ip);
            $ip = reset($ip_arr);
        }
        return $ip;
    }



    protected function asyn_email_send($data) {
        $host = $_SERVER['HTTP_HOST'];
        $param = http_build_query($data);
        $fp = @fsockopen('ssl://' . $host, 443, $errno, $errstr, 20);
        if (!$fp){
            mylog($this->cmd,'error fsockopen','fsockopen.log');
        }else{
            stream_set_blocking($fp,0);
            $http = "GET /manage/email/accountWarning?".$param." HTTP/1.1\r\n";
            $http .= "Host: ". $host ."\r\n";
            $http .= "Connection: Close\r\n\r\n";
            fwrite($fp,$http);
            usleep(1000);
            fclose($fp);
        }
    }



}